from rest_framework import serializers
import re
from .utils import get_user_by_accout
from . import models
from django.contrib.auth.hashers import make_password
from rest_framework_jwt.settings import api_settings
from django_redis import get_redis_connection


class UserModelSerializer(serializers.ModelSerializer):
    sms_code = serializers.CharField(min_length=4, max_length=6, required=True, help_text='短信验证码', write_only=True)
    token = serializers.CharField(max_length=1024, help_text='token认证字符串', read_only=True)

    class Meta:
        model = models.User
        fields = ['mobile', 'password', 'sms_code', 'id', 'username', 'token']
        extra_kwargs = {
            'id': {
                'read_only': True,
            },
            'username': {
                'read_only': True
            },
            'mobile': {
                'write_only': True
            },
            'password': {
                'write_only': True
            }
        }

    def validate(self, attrs):
        """全局钩子"""

        mobile = attrs.get('mobile')
        sms_code = attrs.get('sms_code')
        if not re.match(r'^1[1-9]\d{9}$', mobile):
            raise serializers.ValidationError('对不起，手机号码格式错误')
        if get_user_by_accout(mobile):
            raise serializers.ValidationError('该手机号已被注册')

        # 验证手机验证码是否正确

        redis_conn = get_redis_connection('sms_code')
        redis_sms_code = redis_conn.get(f'sms_{mobile}').decode()
        if sms_code != redis_sms_code:
            raise serializers.ValidationError('验证码输入有误')
        return attrs


    def create(self, validated_data):
        """
        我们要保存新注册的用户的数据
        1. 密码要求是密文
        2. 用户名要随机生成并且带有字母
        :param validated_data:
        :return:
        """

        mobile = validated_data.get('mobile')
        password = validated_data.get('password')
        new_username = f'user_{mobile}'
        new_password = make_password(password)
        user = models.User.objects.create(mobile=mobile, username=new_username, password=new_password)

        jwt_payload_handler = api_settings.JWT_PAYLOAD_HANDLER
        jwt_encode_handler = api_settings.JWT_ENCODE_HANDLER

        payload = jwt_payload_handler(user)
        token = jwt_encode_handler(payload)
        user.token = token

        return user
